<div class="tmd-doc">
<h1 class="tmd-header-1">
Channel Use Cases
</h1>
<p></p>
<div class="tmd-usual">
Before reading this article, please read the article <a href="channel.html">channels in Go</a>, which explains channel types and values in detail. New gophers may need to read that article and the current one several times to master Go channel programming.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
The remaining of this article will show many channel use cases. I hope this article will convince you that
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
asynchronous and concurrency programming with Go channels is easy and enjoyable.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
the channel synchronization technique has a wider range of uses and has more variations than the synchronization solutions used in some other languages, such as <a href="https://en.wikipedia.org/wiki/Actor_model">the actor model</a> and the <a href="https://en.wikipedia.org/wiki/Async/await">async/await pattern</a>.
</div>
</li>
</ul>
<p></p>
<p></p>
<div class="tmd-usual">
Please note that the intention of this article is to show as many channel use cases as possible. We should know that channel is not the only concurrency synchronization technique supported in Go, and for some cases, the channel way may not be the best solution. Please read <a href="concurrent-atomic-operation.html">atomic operations</a> and <a href="concurrent-synchronization-more.html">some other synchronization techniques</a> for more concurrency synchronization techniques in Go.
</div>
<p></p>
<p></p>
<h3 id="future-promise" class="tmd-header-3">
Use Channels as Futures/Promises
</h3>
<p></p>
<div class="tmd-usual">
Futures and promises are used in many other popular languages. They are often associated with requests and responses.
</div>
<p></p>
<h4 class="tmd-header-4">
Return receive-only channels as results
</h4>
<p></p>
<div class="tmd-usual">
In the following example, the values of two arguments of the <code class="tmd-code-span">sumSquares</code> function call are requested concurrently. Each of the two channel receive operations will block until a send operation performs on the corresponding channel. It takes about three seconds instead of six seconds to return the final result.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"time"
	"math/rand"
	"fmt"
)

func longTimeRequest() &lt;-chan int32 {
	r := make(chan int32)

	go func() {
		// Simulate a workload.
		time.Sleep(time.Second * 3)
		r &lt;- rand.Int31n(100)
	}()

	return r
}

func sumSquares(a, b int32) int32 {
	return a*a + b*b
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	a, b := longTimeRequest(), longTimeRequest()
	fmt.Println(sumSquares(&lt;-a, &lt;-b))
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Pass send-only channels as arguments
</h4>
<p></p>
<div class="tmd-usual">
Same as the last example, in the following example, the values of two arguments of the <code class="tmd-code-span">sumSquares</code> function call are requested concurrently. Different to the last example, the <code class="tmd-code-span">longTimeRequest</code> function takes a send-only channel as parameter instead of returning a receive-only channel result.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"time"
	"math/rand"
	"fmt"
)

func longTimeRequest(r chan&lt;- int32)  {
	// Simulate a workload.
	time.Sleep(time.Second * 3)
	r &lt;- rand.Int31n(100)
}

func sumSquares(a, b int32) int32 {
	return a*a + b*b
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	ra, rb := make(chan int32), make(chan int32)
	go longTimeRequest(ra)
	go longTimeRequest(rb)

	fmt.Println(sumSquares(&lt;-ra, &lt;-rb))
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, for the above specified example, we don't need two channels to transfer results. Using one channel is okay.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">...

	// The channel can be buffered or not.
	results := make(chan int32, 2)
	go longTimeRequest(results)
	go longTimeRequest(results)

	fmt.Println(sumSquares(&lt;-results, &lt;-results))
}
</code></pre>
<p></p>
<div class="tmd-usual">
This is kind of data aggregation which will be introduced specially below.
</div>
<p></p>
<h4 id="first-response-wins" class="tmd-header-4">
The first response wins
</h4>
<p></p>
<div class="tmd-usual">
This is the enhancement of the using-only-one-channel variant in the last example.
</div>
<p></p>
<div class="tmd-usual">
Sometimes, a piece of data can be received from several sources to avoid high latencies. For a lot of factors, the response durations of these sources may vary much. Even for a specified source, its response durations are also not constant. To make the response duration as short as possible, we can send a request to every source in a separated goroutine. Only the first response will be used, other slower ones will be discarded.
</div>
<p></p>
<div class="tmd-usual">
Note, if there are <span class="tmd-italic">N</span> sources, the capacity of the communication channel must be at least <span class="tmd-italic">N-1</span>, to avoid the goroutines corresponding the discarded responses being blocked for ever.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"time"
	"math/rand"
)

func source(c chan&lt;- int32) {
	ra, rb := rand.Int31(), rand.Intn(3) + 1
	// Sleep 1s/2s/3s.
	time.Sleep(time.Duration(rb) * time.Second)
	c &lt;- ra
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	startTime := time.Now()
	// c must be a buffered channel.
	c := make(chan int32, 5)
	for i := 0; i &lt; cap(c); i++ {
		go source(c)
	}
	// Only the first response will be used.
	rnd := &lt;- c
	fmt.Println(time.Since(startTime))
	fmt.Println(rnd)
}
</code></pre>
<p></p>
<div class="tmd-usual">
There are some other ways to implement the first-response-win use case, by using the select mechanism and a buffered channel whose capacity is one. Other ways will be introduced below.
</div>
<p></p>
<h4 class="tmd-header-4">
More request-response variants
</h4>
<p></p>
<div class="tmd-usual">
The parameter and result channels can be buffered so that the response sides won't need to wait for the request sides to take out the transferred values.
</div>
<p></p>
<div class="tmd-usual">
Sometimes, a request is not guaranteed to be responded back a valid value. For all kinds of reasons, an error may be returned instead. For such cases, we can use a struct type like <code class="tmd-code-span">struct{v T; err error}</code> or a blank interface type as the channel element type.
</div>
<p></p>
<div class="tmd-usual">
Sometimes, for some reasons, the response may need a much longer time than the expected to arrive, or will never arrive. We can use the timeout mechanism introduced below to handle such circumstances.
</div>
<p></p>
<div class="tmd-usual">
Sometimes, a sequence of values may be returned from the response side, this is kind of the data flow mechanism mentioned later below.
</div>
<p></p>
<h3 id="notification" class="tmd-header-3">
Use Channels for Notifications
</h3>
<p></p>
<div class="tmd-usual">
Notifications can be viewed as special requests/responses in which the responded values are not important. Generally, we use the blank struct type <code class="tmd-code-span">struct{}</code> as the element types of the notification channels, for the size of type <code class="tmd-code-span">struct{}</code> is zero, hence values of <code class="tmd-code-span">struct{}</code> doesn't consume memory.
</div>
<p></p>
<h4 class="tmd-header-4">
1-to-1 notification by sending a value to a channel
</h4>
<p></p>
<div class="tmd-usual">
If there are no values to be received from a channel, then the next receive operation on the channel will block until another goroutine sends a value to the channel. So we can send a value to a channel to notify another goroutine which is waiting to receive a value from the same channel.
</div>
<p></p>
<div class="tmd-usual">
In the following example, the channel <code class="tmd-code-span">done</code> is used as a signal channel to do notifications.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"crypto/rand"
	"fmt"
	"os"
	"sort"
)

func main() {
	values := make([]byte, 32 * 1024 * 1024)
	if _, err := rand.Read(values); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	done := make(chan struct{}) // can be buffered or not

	// The sorting goroutine
	go func() {
		sort.Slice(values, func(i, j int) bool {
			return values[i] &lt; values[j]
		})
		// Notify sorting is done.
		done &lt;- struct{}{}
	}()

	// do some other things ...

	&lt;- done // waiting here for notification
	fmt.Println(values[0], values[len(values)-1])
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
1-to-1 notification by receiving a value from a channel
</h4>
<p></p>
<div class="tmd-usual">
If the value buffer queue of a channel is full (the buffer queue of an unbuffered channel is always full), a send operation on the channel will block until another goroutine receives a value from the channel. So we can receive a value from a channel to notify another goroutine which is waiting to send a value to the same channel. Generally, the channel should be an unbuffered channel.
</div>
<p></p>
<div class="tmd-usual">
This notification way is used much less common than the way introduced in the last example.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"time"
)

func main() {
	done := make(chan struct{})
		// The capacity of the signal channel can
		// also be one. If this is true, then a
		// value must be sent to the channel before
		// creating the following goroutine.

	go func() {
		fmt.Print("Hello")
		// Simulate a workload.
		time.Sleep(time.Second * 2)

		// Receive a value from the done
		// channel, to unblock the second
		// send in main goroutine.
		&lt;- done
	}()

	// Blocked here, wait for a notification.
	done &lt;- struct{}{}
	fmt.Println(" world!")
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, there are no fundamental differences between receiving or sending values to make notifications. They can both be summarized as the fasters are notified by the slowers.
</div>
<p></p>
<h4 class="tmd-header-4">
N-to-1 and 1-to-N notifications
</h4>
<p></p>
<div class="tmd-usual">
By extending the above two use cases a little, it is easy to do N-to-1 and 1-to-N notifications.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "log"
import "time"

type T = struct{}

func worker(id int, ready &lt;-chan T, done chan&lt;- T) {
	&lt;-ready // block here and wait a notification
	log.Print("Worker#", id, " starts.")
	// Simulate a workload.
	time.Sleep(time.Second * time.Duration(id+1))
	log.Print("Worker#", id, " job done.")
	// Notify the main goroutine (N-to-1),
	done &lt;- T{}
}

func main() {
	log.SetFlags(0)

	ready, done := make(chan T), make(chan T)
	go worker(0, ready, done)
	go worker(1, ready, done)
	go worker(2, ready, done)

	// Simulate an initialization phase.
	time.Sleep(time.Second * 3 / 2)
	// 1-to-N notifications.
	ready &lt;- T{}; ready &lt;- T{}; ready &lt;- T{}
	// Being N-to-1 notified.
	&lt;-done; &lt;-done; &lt;-done
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, the ways to do 1-to-N and N-to-1 notifications introduced in this sub-section are not used commonly in practice. In practice, we often use <code class="tmd-code-span">sync.WaitGroup</code> to do N-to-1 notifications, and we do 1-to-N notifications by close channels. Please read the next sub-section for details.
</div>
<p></p>
<h4 class="tmd-header-4">
Broadcast (1-to-N) notifications by closing a channel
</h4>
<p></p>
<div class="tmd-usual">
The way to do 1-to-N notifications shown in the last sub-section is seldom used in practice, for there is a better way. By making using of the feature that infinite values can be received from a closed channel, we can close a channel to broadcast notifications.
</div>
<p></p>
<div class="tmd-usual">
By the example in the last sub-section, we can replace the three channel send operations <code class="tmd-code-span">ready &lt;- struct{}{}</code> in the last example with one channel close operation <code class="tmd-code-span">close(ready)</code> to do an 1-to-N notifications.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">...
	close(ready) // broadcast notifications
...
</code></pre>
<p></p>
<div class="tmd-usual">
Surely, we can also close a channel to do a 1-to-1 notification. In fact, this is the most used notification way in Go.
</div>
<p></p>
<div class="tmd-usual">
The feature that infinite values can be received from a closed channel will be utilized in many other use cases introduced below. In fact, the feature is used popularly in the standard packages. For example, the <code class="tmd-code-span">context</code> package uses this feature to confirm cancellations.
</div>
<p></p>
<h4 id="timer" class="tmd-header-4">
Timer: scheduled notification
</h4>
<p></p>
<div class="tmd-usual">
It is easy to use channels to implement one-time timers.
</div>
<p></p>
<div class="tmd-usual">
A custom one-time timer implementation:
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"time"
)

func AfterDuration(d time.Duration) &lt;- chan struct{} {
	c := make(chan struct{}, 1)
	go func() {
		time.Sleep(d)
		c &lt;- struct{}{}
	}()
	return c
}

func main() {
	fmt.Println("Hi!")
	&lt;- AfterDuration(time.Second)
	fmt.Println("Hello!")
	&lt;- AfterDuration(time.Second)
	fmt.Println("Bye!")
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, the <code class="tmd-code-span">After</code> function in the <code class="tmd-code-span">time</code> standard package provides the same functionality, with a much more efficient implementation. We should use that function instead to make the code look clean.
</div>
<p></p>
<div class="tmd-usual">
Please note, <code class="tmd-code-span">&lt;-time.After(aDuration)</code> will make the current goroutine enter blocking state, but a <code class="tmd-code-span">time.Sleep(aDuration)</code> function call will not.
</div>
<p></p>
<div class="tmd-usual">
The use of <code class="tmd-code-span">&lt;-time.After(aDuration)</code> is often used in the timeout mechanism which will be introduced below.
</div>
<p></p>
<h3 id="mutex" class="tmd-header-3">
Use Channels as Mutex Locks
</h3>
<p></p>
<div class="tmd-usual">
One of the above examples has mentioned that one-capacity buffered channels can be used as one-time <a href="https://en.wikipedia.org/wiki/Semaphore_(programming)">binary semaphore</a>. In fact, such channels can also be used as multi-time binary semaphores, a.k.a., mutex locks, though such mutex locks are not efficient as the mutexes provided in the <code class="tmd-code-span">sync</code> standard package.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
There are two manners to use one-capacity buffered channels as mutex locks.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
Lock through a send, unlock through a receive.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
Lock through a receive, unlock through a send.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
The following is a lock-through-send example.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func main() {
	// The capacity must be one.
	mutex := make(chan struct{}, 1)

	counter := 0
	increase := func() {
		mutex &lt;- struct{}{} // lock
		counter++
		&lt;-mutex // unlock
	}

	increase1000 := func(done chan&lt;- struct{}) {
		for i := 0; i &lt; 1000; i++ {
			increase()
		}
		done &lt;- struct{}{}
	}

	done := make(chan struct{})
	go increase1000(done)
	go increase1000(done)
	&lt;-done; &lt;-done
	fmt.Println(counter) // 2000
}
</code></pre>
<p></p>
<div class="tmd-usual">
The following is a lock-through-receive example. It just shows the modified part based on the above lock-through-send example.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">...
func main() {
	mutex := make(chan struct{}, 1)
	mutex &lt;- struct{}{} // this line is needed.

	counter := 0
	increase := func() {
		&lt;-mutex // lock
		counter++
		mutex &lt;- struct{}{} // unlock
	}
...
</code></pre>
<p></p>
<h3 id="semaphore" class="tmd-header-3">
Use Channels as Counting Semaphores
</h3>
<p></p>
<div class="tmd-usual">
Buffered channels can be used as <a href="https://en.wikipedia.org/wiki/Semaphore_(programming)">counting semaphores</a>. Counting semaphores can be viewed as multi-owner locks. If the capacity of a channel is <code class="tmd-code-span">N</code>, then it can be viewed as a lock which can have most <code class="tmd-code-span">N</code> owners at any time. Binary semaphores (mutexes) are special counting semaphores, each of binary semaphores can have at most one owner at any time.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
Counting semaphores are often used to enforce a maximum number of concurrent requests.
</div>
<p></p>
<div class="tmd-usual">
Like using channels as mutexes, there are also two manners to acquire one piece of ownership of a channel semaphore.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
Acquire ownership through a send, release through a receive.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
Acquire ownership through a receive, release through a send.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
An example of acquiring ownership through receiving values from a channel.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import (
	"log"
	"time"
	"math/rand"
)

type Seat int
type Bar chan Seat

func (bar Bar) ServeCustomer(c int) {
	log.Print("customer#", c, " enters the bar")
	seat := &lt;- bar // need a seat to drink
	log.Print("++ customer#", c, " drinks at seat#", seat)
	time.Sleep(time.Second * time.Duration(2 + rand.Intn(6)))
	log.Print("-- customer#", c, " frees seat#", seat)
	bar &lt;- seat // free seat and leave the bar
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	// the bar has 10 seats.
	bar24x7 := make(Bar, 10)
	// Place seats in an bar.
	for seatId := 0; seatId &lt; cap(bar24x7); seatId++ {
		// None of the sends will block.
		bar24x7 &lt;- Seat(seatId)
	}

	for customerId := 0; ; customerId++ {
		time.Sleep(time.Second)
		go bar24x7.ServeCustomer(customerId)
	}

	// sleeping != blocking
	for {time.Sleep(time.Second)}
}
</code></pre>
<p></p>
<div class="tmd-usual">
In the above example, only the customers each of whom get a seat can drink. So there will be most ten customers are drinking at any given time.
</div>
<p></p>
<div class="tmd-usual">
The last <code class="tmd-code-span">for</code> loop in the <code class="tmd-code-span">main</code> function is to avoid the program exiting. There is a better way, which will be introduced below, to do the job.
</div>
<p></p>
<div class="tmd-usual">
In the above example, although there will be most ten customers are drinking at any given time, there may be more than ten customers are served at the bar at the same time. Some customers are waiting for free seats. Although each customer goroutine consumes much fewer resources than a system thread, the total resources consumed by a large number of goroutines are not negligible. So it is best to create a customer goroutine only if there is an available seat.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">... // same code as the above example

func (bar Bar) ServeCustomerAtSeat(c int, seat Seat) {
	log.Print("++ customer#", c, " drinks at seat#", seat)
	time.Sleep(time.Second * time.Duration(2 + rand.Intn(6)))
	log.Print("-- customer#", c, " frees seat#", seat)
	bar &lt;- seat // free seat and leave the bar
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	bar24x7 := make(Bar, 10)
	for seatId := 0; seatId &lt; cap(bar24x7); seatId++ {
		bar24x7 &lt;- Seat(seatId)
	}

	for customerId := 0; ; customerId++ {
		time.Sleep(time.Second)
		// Need a seat to serve next customer.
		seat := &lt;- bar24x7
		go bar24x7.ServeCustomerAtSeat(customerId, seat)
	}
	for {time.Sleep(time.Second)}
}
</code></pre>
<p></p>
<div class="tmd-usual">
There will be at most about ten live customer goroutines coexisting in the above optimized version (but there will still be a lots of customer goroutines to be created in the program lifetime).
</div>
<p></p>
<div class="tmd-usual">
In a more efficient implementation shown below, at most ten customer serving goroutines will be created in the program lifetime.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">... // same code as the above example

func (bar Bar) ServeCustomerAtSeat(consumers chan int) {
	for c := range consumers {
		seatId := &lt;- bar
		log.Print("++ customer#", c, " drinks at seat#", seatId)
		time.Sleep(time.Second * time.Duration(2 + rand.Intn(6)))
		log.Print("-- customer#", c, " frees seat#", seatId)
		bar &lt;- seatId // free seat and leave the bar
	}
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	bar24x7 := make(Bar, 10)
	for seatId := 0; seatId &lt; cap(bar24x7); seatId++ {
		bar24x7 &lt;- Seat(seatId)
	}

	consumers := make(chan int)
	for i := 0; i &lt; cap(bar24x7); i++ {
		go bar24x7.ServeCustomerAtSeat(consumers)
	}
	
	for customerId := 0; ; customerId++ {
		time.Sleep(time.Second)
		consumers &lt;- customerId
	}
}
</code></pre>
<p></p>
<div class="tmd-usual">
Off-topic: surely, if we don't care about seat IDs (which is common in practice), then the <code class="tmd-code-span">bar24x7</code> semaphore is not essential at all:
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">... // same code as the above example

func ServeCustomer(consumers chan int) {
	for c := range consumers {
		log.Print("++ customer#", c, " drinks at the bar")
		time.Sleep(time.Second * time.Duration(2 + rand.Intn(6)))
		log.Print("-- customer#", c, " leaves the bar")
	}
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	const BarSeatCount = 10
	consumers := make(chan int)
	for i := 0; i &lt; BarSeatCount; i++ {
		go ServeCustomer(consumers)
	}
	
	for customerId := 0; ; customerId++ {
		time.Sleep(time.Second)
		consumers &lt;- customerId
	}
}
</code></pre>
<p></p>
<div class="tmd-usual">
The manner of acquiring semaphore ownership through sending is simpler comparatively. The step of placing seats is not needed.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import (
	"log"
	"time"
	"math/rand"
)

type Customer struct{id int}
type Bar chan Customer

func (bar Bar) ServeCustomer(c Customer) {
	log.Print("++ customer#", c.id, " starts drinking")
	time.Sleep(time.Second * time.Duration(3 + rand.Intn(16)))
	log.Print("-- customer#", c.id, " leaves the bar")
	&lt;- bar // leaves the bar and save a space
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	// The bar can serve most 10 customers
	// at the same time.
	bar24x7 := make(Bar, 10)
	for customerId := 0; ; customerId++ {
		time.Sleep(time.Second * 2)
		customer := Customer{customerId}
		// Wait to enter the bar.
		bar24x7 &lt;- customer
		go bar24x7.ServeCustomer(customer)
	}
	for {time.Sleep(time.Second)}
}
</code></pre>
<p></p>
<p></p>
<h3 class="tmd-header-3">
Dialogue (Ping-Pong)
</h3>
<p></p>
<div class="tmd-usual">
Two goroutines can dialogue through a channel. The following is an example which will print a series of Fibonacci numbers.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"
import "time"
import "os"

type Ball uint64

func Play(playerName string, table chan Ball) {
	var lastValue Ball = 1
	for {
		ball := &lt;- table // get the ball
		fmt.Println(playerName, ball)
		ball += lastValue
		if ball &lt; lastValue { // overflow
			os.Exit(0)
		}
		lastValue = ball
		table &lt;- ball // bat back the ball
		time.Sleep(time.Second)
	}
}

func main() {
	table := make(chan Ball)
	go func() {
		table &lt;- 1 // throw ball on table
	}()
	go Play("A:", table)
	Play("B:", table)
}
</code></pre>
<p></p>
<h3 class="tmd-header-3">
Channel Encapsulated in Channel
</h3>
<p></p>
<div class="tmd-usual">
Sometimes, we can use a channel type as the element type of another channel type. In the following example, <code class="tmd-code-span">chan chan&lt;- int</code> is a channel type which element type is a send-only channel type <code class="tmd-code-span">chan&lt;- int</code>.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

var counter = func (n int) chan&lt;- chan&lt;- int {
	requests := make(chan chan&lt;- int)
	go func() {
		for request := range requests {
			if request == nil {
				n++ // increase
			} else {
				request &lt;- n // take out
			}
		}
	}()

	// Implicitly converted to chan&lt;- (chan&lt;- int)
	return requests
}(0)

func main() {
	increase1000 := func(done chan&lt;- struct{}) {
		for i := 0; i &lt; 1000; i++ {
			counter &lt;- nil
		}
		done &lt;- struct{}{}
	}

	done := make(chan struct{})
	go increase1000(done)
	go increase1000(done)
	&lt;-done; &lt;-done

	request := make(chan int, 1)
	counter &lt;- request
	fmt.Println(&lt;-request) // 2000
}
</code></pre>
<p></p>
<div class="tmd-usual">
Although here the encapsulation implementation may be not the most efficient way for the above-specified example, the use case may be useful for some other scenarios.
</div>
<p></p>
<h3 class="tmd-header-3">
Check Lengths and Capacities of Channels
</h3>
<p></p>
<div class="tmd-usual">
We can use the built-in functions <code class="tmd-code-span">len</code> and <code class="tmd-code-span">cap</code> to check the length and capacity of a channel. However, we seldom do this in practice. The reason for we seldom use the <code class="tmd-code-span">len</code> function to check the length of a channel is the length of the channel may have changed after the <code class="tmd-code-span">len</code> function call returns. The reason for we seldom use the <code class="tmd-code-span">cap</code> function to check the capacity of a channel is the capacity of the channel is often known or not important.
</div>
<p></p>
<div class="tmd-usual">
However, there do have some scenarios we need to use the two functions. For example, sometimes, we want to receive all the values buffered in a non-closed channel <code class="tmd-code-span">c</code> which no ones will send values to any more, then we can use the following code to receive remaining values.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">// Assume the current goroutine is the only
// goroutine tries to receive values from
// the channel c at present.
for len(c) &gt; 0 {
	value := &lt;-c
	// use value ...
}
</code></pre>
<p></p>
<div class="tmd-usual">
We can also use the try-receive mechanism introduced below to do the same job. The efficiencies of the two ways are almost the same. The advantage of the try-receive mechanism is the current goroutine is not required to be the only receiving goroutine.
</div>
<p></p>
<div class="tmd-usual">
Sometimes, a goroutine may want to write some values to a buffered channel <code class="tmd-code-span">c</code> until it is full without entering blocking state at the end, and the goroutine is the only sender of the channel, then we can use the following code to do this job.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">for len(c) &lt; cap(c) {
	c &lt;- aValue
}
</code></pre>
<p></p>
<div class="tmd-usual">
Surely, we can also use the try-send mechanism introduced below to do the same job.
</div>
<p></p>
<h3 class="tmd-header-3">
Block the Current Goroutine Forever
</h3>
<p></p>
<div class="tmd-usual">
The select mechanism is a unique feature in Go. It brings many patterns and tricks for concurrent programming. About the code execution rules of the select mechanism, please read the article <a href="channel.html#select">channels in Go</a>.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
We can use a blank select block <code class="tmd-code-span">select{}</code> to block the current goroutine for ever. This is the simplest use case of the select mechanism. In fact, some uses of <code class="tmd-code-span">for {time.Sleep(time.Second)}</code> in some above examples can be replaced with <code class="tmd-code-span">select{}</code>.
</div>
<p></p>
<div class="tmd-usual">
Generally, <code class="tmd-code-span">select{}</code> is used to prevent the main goroutine from exiting, for if the main goroutine exits, the whole program will also exit.
</div>
<p></p>
<div class="tmd-usual">
An example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "runtime"

func DoSomething() {
	for {
		// do something ...

		runtime.Gosched() // avoid being greedy
	}
}

func main() {
	go DoSomething()
	go DoSomething()
	select{}
}
</code></pre>
<p></p>
<div class="tmd-usual">
By the way, there are <a href="summaries.html#block-forever">some other ways</a> to make a goroutine stay in blocking state for ever. But the <code class="tmd-code-span">select{}</code> way is the simplest one.
</div>
<p></p>
<p></p>
<h3 id="try-operation" class="tmd-header-3">
Try-Send and Try-Receive
</h3>
<p></p>
<div class="tmd-usual">
A <code class="tmd-code-span">select</code> block with one <code class="tmd-code-span">default</code> branch and only one <code class="tmd-code-span">case</code> branch is called a try-send or try-receive channel operation, depending on whether the channel operation following the <code class="tmd-code-span">case</code> keyword is a channel send or receive operation.
</div>
<p></p>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
If the operation following the <code class="tmd-code-span">case</code> keyword is a send operation, then the <code class="tmd-code-span">select</code> block is called as try-send operation. If the send operation would block, then the <code class="tmd-code-span">default</code> branch will get executed (fail to send), otherwise, the send succeeds and the only <code class="tmd-code-span">case</code> branch will get executed.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
If the operation following the <code class="tmd-code-span">case</code> keyword is a receive operation, then the <code class="tmd-code-span">select</code> block is called as try-receive operation. If the receive operation would block, then the <code class="tmd-code-span">default</code> branch will get executed (fail to receive), otherwise, the receive succeeds and the only <code class="tmd-code-span">case</code> branch will get executed.
</div>
</li>
</ul>
<p></p>
<div class="tmd-usual">
Try-send and try-receive operations never block.
</div>
<p></p>
<div class="tmd-usual">
The standard Go compiler makes special optimizations for try-send and try-receive select blocks, their execution efficiencies are much higher than multi-case select blocks.
</div>
<p></p>
<div class="tmd-usual">
The following is an example which shows how try-send and try-receive work.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import "fmt"

func main() {
	type Book struct{id int}
	bookshelf := make(chan Book, 3)

	for i := 0; i &lt; cap(bookshelf) * 2; i++ {
		select {
		case bookshelf &lt;- Book{id: i}:
			fmt.Println("succeeded to put book", i)
		default:
			fmt.Println("failed to put book")
		}
	}

	for i := 0; i &lt; cap(bookshelf) * 2; i++ {
		select {
		case book := &lt;-bookshelf:
			fmt.Println("succeeded to get book", book.id)
		default:
			fmt.Println("failed to get book")
		}
	}
}
</code></pre>
<p></p>
<div class="tmd-usual">
The output of the above program:
</div>
<p></p>
<pre class="tmd-code output">
succeed to put book 0
succeed to put book 1
succeed to put book 2
failed to put book
failed to put book
failed to put book
succeed to get book 0
succeed to get book 1
succeed to get book 2
failed to get book
failed to get book
failed to get book
</pre>
<p></p>
<div class="tmd-usual">
The following sub-sections will show more try-send and try-receive use cases.
</div>
<p></p>
<h4 id="check-closed-status" class="tmd-header-4">
Check if a channel is closed without blocking the current goroutine
</h4>
<p></p>
<div class="tmd-usual">
Assume it is guaranteed that no values were ever (and will be) sent to a channel, we can use the following code to (concurrently and safely) check whether or not the channel is already closed without blocking the current goroutine, where <code class="tmd-code-span">T</code> the element type of the corresponding channel type.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func IsClosed(c chan T) bool {
	select {
	case &lt;-c:
		return true
	default:
	}
	return false
}
</code></pre>
<p></p>
<div class="tmd-usual">
The way to check if a channel is closed is used popularly in Go concurrent programming to check whether or not a notification has arrived. The notification will be sent by closing the channel in another goroutine.
</div>
<p></p>
<h4 id="peak-limiting" class="tmd-header-4">
Peak/burst limiting
</h4>
<p></p>
<div class="tmd-usual">
We can implement peak limiting by combining <a href="#semaphore">use channels as counting semaphores</a> and try-send/try-receive. Peak-limit (or burst-limit) is often used to limit the number of concurrent requests without blocking any requests.
</div>
<p></p>
<div class="tmd-usual">
The following is a modified version of the last example in the <a href="#semaphore">use channels as counting semaphores</a> section.
</div>
<p></p>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">...
	// Can serve most 10 customers at the same time
	bar24x7 := make(Bar, 10)
	for customerId := 0; ; customerId++ {
		time.Sleep(time.Second)
		customer := Consumer{customerId}
		select {
		case bar24x7 &lt;- customer: // try to enter the bar
			go bar24x7.ServeConsumer(customer)
		default:
			log.Print("customer#", customerId, " goes elsewhere")
		}
	}
...
</code></pre>
<p></p>
<h4 id="first-response-wins-2" class="tmd-header-4">
Another way to implement the first-response-wins use case
</h4>
<p></p>
<div class="tmd-usual">
As mentioned above, we can use the select mechanism (try-send) with a buffered channel which capacity is one (at least) to implement the first-response-wins use case. For example,
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"math/rand"
	"time"
)

func source(c chan&lt;- int32) {
	ra, rb := rand.Int31(), rand.Intn(3)+1
	// Sleep 1s, 2s or 3s.
	time.Sleep(time.Duration(rb) * time.Second)
	select {
	case c &lt;- ra:
	default:
	}
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	// The capacity should be at least 1.
	c := make(chan int32, 1)
	for i := 0; i &lt; 5; i++ {
		go source(c)
	}
	rnd := &lt;-c // only the first response is used
	fmt.Println(rnd)
}
</code></pre>
<p></p>
<div class="tmd-usual">
Please note, the capacity of the channel used in the above example must be at least one, so that the first send won't be missed if the receiver/request side has not gotten ready in time.
</div>
<p></p>
<h4 id="first-response-wins-3" class="tmd-header-4">
The third way to implement the first-response-wins use case
</h4>
<p></p>
<div class="tmd-usual">
For a first-response-wins use case, if the number of sources is small, for example, two or three, we can use a <code class="tmd-code-span">select</code> code block to receive the source responses at the same time. For example,
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import (
	"fmt"
	"math/rand"
	"time"
)

func source() &lt;-chan int32 {
	// c must be a buffered channel.
	c := make(chan int32, 1)
	go func() {
		ra, rb := rand.Int31(), rand.Intn(3)+1
		time.Sleep(time.Duration(rb) * time.Second)
		c &lt;- ra
	}()
	return c
}

func main() {
	rand.Seed(time.Now().UnixNano()) // needed before Go 1.20

	var rnd int32
	// Blocking here until one source responses.
	select{
	case rnd = &lt;-source():
	case rnd = &lt;-source():
	case rnd = &lt;-source():
	}
	fmt.Println(rnd)
}
</code></pre>
<p></p>
<div class="tmd-usual">
Note: if the channel used in the above example is an unbuffered channel, then there will two goroutines hanging for ever after the <code class="tmd-code-span">select</code> code block is executed. This is <a href="memory-leaking.html#hanging-goroutine">a memory leak case</a>.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
The two ways introduced in the current and the last sub-sections can also be used to do N-to-1 notifications.
</div>
<p></p>
<h4 class="tmd-header-4">
Timeout
</h4>
<p></p>
<div class="tmd-usual">
In some request-response scenarios, for all kinds of reasons, a request may need a long time to response, sometimes even will never response. For such cases, we should return an error message to the client side by using a timeout solution. Such a timeout solution can be implemented with the select mechanism.
</div>
<p></p>
<div class="tmd-usual">
The following code shows how to make a request with a timeout.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func requestWithTimeout(timeout time.Duration) (int, error) {
	c := make(chan int)
	// May need a long time to get the response.
	go doRequest(c)

	select {
	case data := &lt;-c:
		return data, nil
	case &lt;-time.After(timeout):
		return 0, errors.New("timeout")
	}
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Ticker
</h4>
<p></p>
<div class="tmd-usual">
We can use the try-send mechanism to implement a ticker.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"
import "time"

func Tick(d time.Duration) &lt;-chan struct{} {
	// The capacity of c is best set as one.
	c := make(chan struct{}, 1)
	go func() {
		for {
			time.Sleep(d)
			select {
			case c &lt;- struct{}{}:
			default:
			}
		}
	}()
	return c
}

func main() {
	t := time.Now()
	for range Tick(time.Second) {
		fmt.Println(time.Since(t))
	}
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, there is a <code class="tmd-code-span">Tick</code> function in the <code class="tmd-code-span">time</code> standard package provides the same functionality, with a much more efficient implementation. We should use that function instead to make code look clean and run efficiently.
</div>
<p></p>
<h4 id="rate-limiting" class="tmd-header-4">
Rate Limiting
</h4>
<p></p>
<div class="tmd-usual">
One of above section has shown how to use try-send to do <a href="#peak-limiting">peak limiting</a>. We can also use try-send to do rate limiting (with the help of a ticker). In practice, rate-limit is often to avoid quota exceeding and resource exhaustion.
</div>
<p></p>
<div class="tmd-usual">
The following shows such an example borrowed from jh oh <a href="https://github.com/golang/go/wiki/RateLimiting">the official Go wiki</a>. In this example, the number of handled requests in any one-minute duration will not exceed 200.
</div>
<p></p>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import "fmt"
import "time"

type Request interface{}
func handle(r Request) {fmt.Println(r.(int))}

const RateLimitPeriod = time.Minute
const RateLimit = 200 // most 200 requests in one minute

func handleRequests(requests &lt;-chan Request) {
	quotas := make(chan time.Time, RateLimit)

	go func() {
		tick := time.NewTicker(RateLimitPeriod / RateLimit)
		defer tick.Stop()
		for t := range tick.C {
			select {
			case quotas &lt;- t:
			default:
			}
		}
	}()

	for r := range requests {
		&lt;-quotas
		go handle(r)
	}
}

func main() {
	requests := make(chan Request)
	go handleRequests(requests)
	// time.Sleep(time.Minute)
	for i := 0; ; i++ {requests &lt;- i}
}
</code></pre>
<p></p>
<div class="tmd-usual">
In practice, we often use rate-limit and peak/burst-limit together.
</div>
<p></p>
<h4 class="tmd-header-4">
Switches
</h4>
<p></p>
<div class="tmd-usual">
From the article <a href="channel.html">channels in Go</a>, we have learned that sending a value to or receiving a value from a nil channel are both blocking operations. By making use of this fact, we can change the involved channels in the <code class="tmd-code-span">case</code> operations of a <code class="tmd-code-span">select</code> code block to affect the branch selection in the <code class="tmd-code-span">select</code> code block.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
The following is another ping-pong example which is implemented by using the select mechanism. In this example, one of the two channel variables involved in the select block is <code class="tmd-code-span">nil</code>. The <code class="tmd-code-span">case</code> branch corresponding the nil channel will not get selected for sure. We can think such <code class="tmd-code-span">case</code> branches are in off status. At the end of each loop step, the on/off statuses of the two <code class="tmd-code-span">case</code> branches are switched.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import "fmt"
import "time"
import "os"

type Ball uint8
func Play(playerName string, table chan Ball, serve bool) {
	var receive, send chan Ball
	if serve {
		receive, send = nil, table
	} else {
		receive, send = table, nil
	}
	var lastValue Ball = 1
	for {
		select {
		case send &lt;- lastValue:
		case value := &lt;- receive:
			fmt.Println(playerName, value)
			value += lastValue
			if value &lt; lastValue { // overflow
				os.Exit(0)
			}
			lastValue = value
		}
		// Switch on/off.
		receive, send = send, receive
		time.Sleep(time.Second)
	}
}

func main() {
	table := make(chan Ball)
	go Play("A:", table, false)
	Play("B:", table, true)
}
</code></pre>
<p></p>
<div class="tmd-usual">
The following is another (non-concurrent) example which is much simpler and also demos the switch effect. This example will print <code class="tmd-code-span">1212...</code> when running. It has not much usefulness in practice. It is shown here just for learning purpose.
</div>
<p></p>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

import "fmt"
import "time"

func main() {
	for c := make(chan struct{}, 1); true; {
		select {
		case c &lt;- struct{}{}:
			fmt.Print("1")
		case &lt;-c:
			fmt.Print("2")
		}
		time.Sleep(time.Second)
	}
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Control code execution possibility weights
</h4>
<p></p>
<div class="tmd-usual">
We can duplicate a <code class="tmd-code-span">case</code> branch in a <code class="tmd-code-span">select</code> code block to increase the execution possibility weigh of the corresponding code.
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func main() {
	foo, bar := make(chan struct{}), make(chan struct{})
	close(foo); close(bar) // for demo purpose
	x, y := 0.0, 0.0
	f := func(){x++}
	g := func(){y++}
	for i := 0; i &lt; 100000; i++ {
		select {
		case &lt;-foo: f()
		case &lt;-foo: f()
		case &lt;-bar: g()
		}
	}
	fmt.Println(x/y) // about 2
}
</code></pre>
<p></p>
<div class="tmd-usual">
The possibility of the <code class="tmd-code-span">f</code> function being called is about the double of the <code class="tmd-code-span">g</code> function being called.
</div>
<p></p>
<h4 class="tmd-header-4">
Select from dynamic number of cases
</h4>
<p></p>
<div class="tmd-usual">
Although the number of branches in a <code class="tmd-code-span">select</code> block is fixed, we can use the functionalities provided in the <code class="tmd-code-span">reflect</code> standard package to construct a select block at run time. The dynamically created select block can have an arbitrary number of case branches. But please note, the reflection way is less efficient than the fixed way.
</div>
<p></p>
<div class="tmd-usual">
The <code class="tmd-code-span">reflect</code> standard package also provides <code class="tmd-code-span">TrySend</code> and <code class="tmd-code-span">TryRecv</code> functions to implement one-case-plus-default select blocks.
</div>
<p></p>
<h3 id="data-flow" class="tmd-header-3">
Data Flow Manipulations
</h3>
<p></p>
<div class="tmd-usual">
This section will introduce some data flow manipulation use cases by using channels.
</div>
<p></p>
<div class="tmd-usual">
Generally, a data flow application consists of many modules. Different modules do different jobs. Each module may own one or several workers (goroutines), which concurrently do the same job specified for that module. Here is a list of some module job examples in practice:
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
data generation/collecting/loading.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
data serving/saving.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
data calculation/analysis.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
data validation/filtering.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
data aggregation/division
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
data composition/decomposition.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
data duplication/proliferation.
</div>
</li>
</ul>
<p></p>
<div class="tmd-usual">
A worker in a module may receive data from several other modules as inputs and send data to serve other modules as outputs. In other words, a module can be both a data consumer and a data producer. A module which only sends data to some other modules but never receives data from other modules is called a producer-only module. A module which only receives data from some other modules but never sends data to other modules is called a consumer-only module.
</div>
<p></p>
<div class="tmd-usual">
Many modules together form a data flow system.
</div>
<p></p>
<div class="tmd-usual">
The following will show some data flow module worker implementations. These implementations are for explanation purpose, so they are very simple and they may be not efficient.
</div>
<p></p>
<h4 class="tmd-header-4">
Data generation/collecting/loading
</h4>
<p></p>
<div class="tmd-usual">
There are all kinds of producer-only modules. A producer-only module worker may produce a data stream
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
by loading a file, reading a database, or crawling the web.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
by collecting all kinds of metrics from a software system or all kinds of hardware.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
by generating random numbers.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
etc.
</div>
</li>
</ul>
<p></p>
<div class="tmd-usual">
Here, we use a random number generator as an example. The generator function returns one result but takes no parameters.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">import (
	"crypto/rand"
	"encoding/binary"
)

func RandomGenerator() &lt;-chan uint64 {
	c := make(chan uint64)
	go func() {
		rnds := make([]byte, 8)
		for {
			_, err := rand.Read(rnds)
			if err != nil {
				close(c)
				break
			}
			c &lt;- binary.BigEndian.Uint64(rnds)
		}
	}()
	return c
}
</code></pre>
<p></p>
<div class="tmd-usual">
In fact, the random number generator is a multi-return future/promise.
</div>
<p></p>
<div class="tmd-usual">
A data producer may close the output stream channel at any time to end data generating.
</div>
<p></p>
<h4 class="tmd-header-4">
Data aggregation
</h4>
<p></p>
<div class="tmd-usual">
A data aggregation module worker aggregates several data streams of the same data type into one stream. Assume the data type is <code class="tmd-code-span">int64</code>, then the following function will aggregate an arbitrary number of data streams into one.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func Aggregator(inputs ...&lt;-chan uint64) &lt;-chan uint64 {
	out := make(chan uint64)
	for _, in := range inputs {
		go func(in &lt;-chan uint64) {
			for {
				out &lt;- &lt;-in // &lt;=&gt; out &lt;- (&lt;-in)
			}
		}(in)
	}
	return out
}
</code></pre>
<p></p>
<div class="tmd-usual">
A better implementation should consider whether or not an input stream has been closed. (Also valid for the following other module worker implementations.)
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">import "sync"

func Aggregator(inputs ...&lt;-chan uint64) &lt;-chan uint64 {
	output := make(chan uint64)
	var wg sync.WaitGroup
	for _, in := range inputs {
		wg.Add(1)
		go func(int &lt;-chan uint64) {
			defer wg.Done()
			// If in is closed, then the
			// loop will ends eventually.
			for x := range in {
				output &lt;- x
			}
		}(in)
	}
	go func() {
		wg.Wait()
		close(output)
	}()
	return output
}
</code></pre>
<p></p>
<div class="tmd-usual">
If the number of aggregated data streams is very small (two or three), we can use <code class="tmd-code-span">select</code> block to aggregate these data streams.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">// Assume the number of input stream is two.
...
	output := make(chan uint64)
	go func() {
		inA, inB := inputs[0], inputs[1]
		for {
			select {
			case v := &lt;- inA: output &lt;- v
			case v := &lt;- inB: output &lt;- v
			}
		}
	}
...
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Data division
</h4>
<p></p>
<div class="tmd-usual">
A data division module worker does the opposite of a data aggregation module worker. It is easy to implement a division worker, but in practice, division workers are not very useful and seldom used.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func Divisor(input &lt;-chan uint64, outputs ...chan&lt;- uint64) {
	for _, out := range outputs {
		go func(o chan&lt;- uint64) {
			for {
				o &lt;- &lt;-input // &lt;=&gt; o &lt;- (&lt;-input)
			}
		}(out)
	}
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Data composition
</h4>
<p></p>
<div class="tmd-usual">
A data composition worker merges several pieces of data from different input data streams into one piece of data.
</div>
<p></p>
<div class="tmd-usual">
The following is a composition worker example, in which two <code class="tmd-code-span">uint64</code> values from one stream and one <code class="tmd-code-span">uint64</code> value from another stream compose one new <code class="tmd-code-span">uint64</code> value. Surely, these stream channel element types are different generally in practice.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func Composer(inA, inB &lt;-chan uint64) &lt;-chan uint64 {
	output := make(chan uint64)
	go func() {
		for {
			a1, b, a2 := &lt;-inA, &lt;-inB, &lt;-inA
			output &lt;- a1 ^ b &amp; a2
		}
	}()
	return output
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Data decomposition
</h4>
<p></p>
<div class="tmd-usual">
Data decomposition is the inverse process of data composition. A decomposition worker function implementation takes one input data stream parameter and returns several data stream results. No examples will be shown for data decomposition here.
</div>
<p></p>
<h4 class="tmd-header-4">
Data duplication/proliferation
</h4>
<p></p>
<div class="tmd-usual">
Data duplication (proliferation) can be viewed as special data decompositions. One piece of data will be duplicated and each of the duplicated data will be sent to different output data streams.
</div>
<p></p>
<div class="tmd-usual">
An example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">func Duplicator(in &lt;-chan uint64) (&lt;-chan uint64, &lt;-chan uint64) {
	outA, outB := make(chan uint64), make(chan uint64)
	go func() {
		for x := range in {
			outA &lt;- x
			outB &lt;- x
		}
	}()
	return outA, outB
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Data calculation/analysis
</h4>
<p></p>
<div class="tmd-usual">
The functionalities of data calculation and analysis modules vary and each is very specific. Generally, a worker function of such modules transforms each piece of input data into another piece of output data.
</div>
<p></p>
<div class="tmd-usual">
For simple demo purpose, here shows a worker example which inverts every bit of each transferred <code class="tmd-code-span">uint64</code> value.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">func Calculator(in &lt;-chan uint64, out chan uint64) (&lt;-chan uint64) {
	if out == nil {
		out = make(chan uint64)
	}
	go func() {
		for x := range in {
			out &lt;- ^x
		}
	}()
	return out
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Data validation/filtering
</h4>
<p></p>
<div class="tmd-usual">
A data validation or filtering module discards some transferred data in a stream. For example, the following worker function discards all non-prime numbers.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">import "math/big"

func Filter0(input &lt;-chan uint64, output chan uint64) &lt;-chan uint64 {
	if output == nil {
		output = make(chan uint64)
	}
	go func() {
		bigInt := big.NewInt(0)
		for x := range input {
			bigInt.SetUint64(x)
			if bigInt.ProbablyPrime(1) {
				output &lt;- x
			}
		}
	}()
	return output
}

func Filter(input &lt;-chan uint64) &lt;-chan uint64 {
	return Filter0(input, nil)
}
</code></pre>
<p></p>
<div class="tmd-usual">
Please note that each of the two implementations is used by one of the final two examples shown below.
</div>
<p></p>
<h4 class="tmd-header-4">
Data serving/saving
</h4>
<p></p>
<div class="tmd-usual">
Generally, a data serving or saving module is the last or final output module in a data flow system. Here just provides a simple worker which prints each piece of data received from the input stream.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">import "fmt"

func Printer(input &lt;-chan uint64) {
	for x := range input {
		fmt.Println(x)
	}
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
Data flow system assembling
</h4>
<p></p>
<div class="tmd-usual">
Now, let's use the above module worker functions to assemble several data flow systems. Assembling a data flow system is just to create some workers of different modules, and specify the input streams for every worker.
</div>
<p></p>
<div class="tmd-usual">
Data flow system example 1 (a linear pipeline):
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

... // the worker functions declared above.

func main() {
	Printer(
		Filter(
			Calculator(
				RandomGenerator(), nil,
			),
		),
	)
}
</code></pre>
<p></p>
<div class="tmd-usual">
The above data flow system is depicted in the following diagram.
</div>
<p></p>
<div class="tmd-base tmd-align-center">
<div class="tmd-usual">
<img src="res/data-flow-linear.png" class="tmd-media"/>
</div>
</div>
<p></p>
<div class="tmd-usual">
Data flow system example 2 (a directed acyclic graph pipeline):
</div>
<pre class="tmd-code line-numbers must-line-numbers">
<code class="language-go">package main

... // the worker functions declared above.

func main() {
	filterA := Filter(RandomGenerator())
	filterB := Filter(RandomGenerator())
	filterC := Filter(RandomGenerator())
	filter := Aggregator(filterA, filterB, filterC)
	calculatorA := Calculator(filter, nil)
	calculatorB := Calculator(filter, nil)
	calculator := Aggregator(calculatorA, calculatorB)
	Printer(calculator)
}
</code></pre>
<p></p>
<div class="tmd-usual">
The above data flow system is depicted in the following diagram.
</div>
<p></p>
<div class="tmd-base tmd-align-center">
<div class="tmd-usual">
<img src="res/data-flow-dag.png" class="tmd-media"/>
</div>
</div>
<p></p>
<div class="tmd-usual">
More complex data flow topology may be arbitrary graphs. For example, a data flow system may have multiple final outputs. But data flow systems with cyclic-graph topology are seldom used in reality.
</div>
<p></p>
<div class="tmd-usual">
From the above two examples, we can find that it is very easy and intuitive to build data flow systems with channels.
</div>
<p></p>
<div class="tmd-usual">
From the last example, we can find that, with the help of aggregators, it is easy to implement fan-in and fan-out for the number of workers for a specified module.
</div>
<p></p>
<div class="tmd-usual">
In fact, we can use a simple channel to replace the role of an aggregator. For example, the following example replaces the two aggregators with two channels.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

... // the worker functions declared above.

func main() {
	c1 := make(chan uint64, 100)
	Filter0(RandomGenerator(), c1) // filterA
	Filter0(RandomGenerator(), c1) // filterB
	Filter0(RandomGenerator(), c1) // filterC
	c2 := make(chan uint64, 100)
	Calculator(c1, c2) // calculatorA
	Calculator(c1, c2) // calculatorB
	Printer(c2)
}
</code></pre>
<p></p>
<div class="tmd-usual">
The modified data flow system is depicted in the following diagram.
</div>
<p></p>
<div class="tmd-base tmd-align-center">
<div class="tmd-usual">
<img src="res/data-flow-dag-b.png" class="tmd-media"/>
</div>
</div>
<p></p>
<div class="tmd-usual">
The above explanations for data flow systems don't consider much on how to close data streams. Please read <a href="channel-closing.html">this article</a> for explanations on how to gracefully close channels.
</div>
<p></p>
<p></p>
<p></p>
</div>
